/**
 * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "GPURender.h"
#include "napi_tool.h"
#include <native_window/external_window.h>

GPURender *GPURender::instance = nullptr;
std::once_flag GPURender::onceFlag;

GPURender *GPURender::getInstance()
{
    std::call_once(onceFlag, []() {
        instance = new GPURender();
    });
    return instance;
}

GPURender::GPURender() {}

GPURender::~GPURender() {}

void GPURender::setCallback(std::shared_ptr<CallbackListener> callback)
{
    if (renderThread) {
        renderThread->setCallback(callback);
    } else {
        LOGE("renderThread is null!");
    }
}

uint64_t GPURender::getSurfaceId()
{
    if (renderThread) {
        return renderThread->getSurfaceId();
    } else {
        LOGE("renderThread is null!");
        return 0;
    }
}

void GPURender::updateXComponentSize(int width, int height)
{
    if (renderThread) {
        renderThread->updateXComponentSize(width, height);
    } else {
        LOGE("renderThread is null!");
    }
}

void GPURender::setFilter(std::shared_ptr<GPUImageFilter> filter)
{
    if (renderThread) {
        renderThread->setFilter(filter);
    } else {
        LOGE("renderThread is null!");
    }
}

void GPURender::savePixelMap(std::shared_ptr<CallbackListener> callback)
{
    if (renderThread) {
        renderThread->savePixelMap(callback);
    } else {
        LOGE("renderThread is null!");
    }
}

void GPURender::releaseRenderThread()
{
    if (renderThread) {
        renderThread->releaseResources();
        renderThread = nullptr;
    }
}

void GPURender::dumpImage(const std::string &path)
{
    if (renderThread) {
        renderThread->dumpImageRequest(path);
    } else {
        LOGE("renderThread is null!");
    }
}

void GPURender::runOnDraw(std::function<void()> task)
{
    if (renderThread) {
        renderThread->runOnDraw(task);
    } else {
        LOGE("renderThread is null!");
    }
}

void GPURender::startRenderThread(void *nativeWindow, uint64_t width,
                                  uint64_t height)
{
    if (renderThread) {
        renderThread->releaseResources();
        renderThread = nullptr;
    }
    renderThread = std::make_unique<GPURenderThread>();
    renderThread->start(nativeWindow, width, height);
}

void GPURender::setOrientation(Rotation rotation, bool flipX, bool flipY)
{
    if (renderThread) {
        renderThread->setOrientation(rotation, flipX, flipY);
    }
}